//
//  stringConstruction.hpp
//  learnC++
//
//  Created by liuzhibing on 2018/7/7.
//  Copyright © 2018年 yunfan.com. All rights reserved.
//

#ifndef stringConstruction_hpp
#define stringConstruction_hpp

#include <stdio.h>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <cstring>

using namespace std;

template <class T>
class TestString {
private:
    T m_value;
    
public:
    
    TestString(T value):m_value(value){
        
    }
    
    ~TestString(){
        
    }
    
    void printSelf();
    
    void stringTest1(){
        std::string name = "alex";
        
        std::string mm(name,3);
        
        std::string m2(name,2,2);
        
        const char *cStr = "cString";
        std::string m3(cStr);
        std::string m4(cStr,3);
        std::string m5(4,'Q');
        
        //Format
//        将数字转换为字符串的最简单方法是使用std :: ostringstream类。 std :: ostringstream已经设置为接受来自各种来源的输入，包括字符，数字，字符串等...它还能够输出字符串（通过提取运算符>>或通过str（）函数）
        std::stringstream m6;
        m6 << 1234 << "alex" << 5678;
        std::string m7 = m6.str();
        
        
        //cString和std::string相互转换

//        除非你需要所有的效率，否则c_str（）是三个函数中最容易和最安全的。
        
        std::string cs(cStr);
//        C样式字符串由std :: string拥有，不应delete
        const char *m8 =  cs.c_str();
        //或者(C样式字符串由std :: string拥有，不应delete)
        const char *m9 = cs.data();
        
        //或
        char p[10];
        cs.copy(p,7);
        *(p+7) = '\0';
        
        //或
        char ptr[10];
        for (int i = 0; i < cs.length(); ++i) {
            ptr[i] = cs[i];
        }
        
        int res = memcmp(m9, m8, cs.length());
        
        //string.size()等同于length();
        ptr[cs.length()] = '\0';
//        返回字符串在不重新分配的情况下可以容纳的字符数。
        std::cout << cs.capacity() << "\n";
        
        std::cout << cs.max_size() << "\n";
        
        std::string &refstr = cs;
        //存储空间
        cs.reserve(50);
        cs += "xnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn";
        
        
        
        int a = arc4random()%1000;
        
        //operator[]  return char &
        cs[0] = 'V';
        cs.at(1) = 'X';
        
        std::cout << refstr;
        
        printf("..");
    }
    
    void stringTest2(){
        //string的分配
        string sString;
        
        sString = string("One");
        cout << sString << endl;
        
        const string sTwo("Two");
        sString.assign(sTwo);
        cout << sString << endl;
        
        sString = "Three";
        cout << sString << endl;
        
        sString.assign("Four");
        cout << sString << endl;
        
        sString = '5';
        cout << sString << endl;
        
        string sother;
        sString = sother = "Six";
        cout << sString << sother << endl;
        
        sString.assign(sother,2,1);// assign a substring of source from index 2 of length 1
        cout << sString << endl;
        
        sString.assign("abcdefg"/*,2*/,4);
        cout << sString << endl;
        
        sString.assign(4,'g');
        cout << sString << endl;
        
        string des("str2");
        cout << sString << des << endl;
        swap(sString, des);
        cout << sString << des << endl;
        
        sString.swap(des);
        cout << sString << des << endl;
    }
    
    void stringTest3(){
        //std::string
        string sString("one");
        
        sString += string("two");
        
        string sThree("three");
        sString.append(sThree);
        
        cout << sString << endl;
        
        sString.append(sThree,2,2);
        
        cout << sString << endl;
        
        //char *
        sString += "five";
        cout << sString << endl;
        sString.append("six",2);
        cout << sString << endl;
        
        //char c
        sString += ' ';
        
        sString.push_back('2');
        cout << sString << endl;
        
        sString.append(4,'b');
        cout << sString << endl;
        
        //iterator
        string des = "xxx";
        string::iterator it = des.begin();
        
        sString.append(it, des.end());
        cout << sString << endl;
        
    }
    
    //insert
    void stringTest4(){
        //std::string and char *
        string sString("one");
        cout << sString << endl;
        
        sString.insert(2, string("bbbb"));
        cout << sString << endl;
        
        sString.insert(2, "cccc");
        cout << sString << endl;
        
        string src("123456789");
        sString.insert(2, src, 3,4);// insert substring of sInsert from index [3,7) into sString at index 2
        cout << sString << endl;
        
        sString.insert(2, "abcdef",3);
        cout << sString << endl;
        
        sString.insert(2, 4,'v');
        cout << sString << endl;
        
        //iterator
        
//        void insert(iterator it, size_type num, char c)
//        iterator string::insert(iterator it, char c)
//        void string::insert(iterator it, InputIterator begin, InputIterator end)
        
        string::iterator it = sString.begin();
        sString.insert(it, 'm');
        cout << sString << endl;
        
    }
    
    
};

template <class T>
void TestString<T>::printSelf(){
    
    std::cout << "Test string\n";
}


#endif /* stringConstruction_hpp */
